package day_04_03_JUCAssistClass;

import java.util.concurrent.CountDownLatch;

/**
 * @Description
 * @Author shihan
 * @Date 2020/11/1 15:16
 * @Version 1.0
 */
public class CountDownLatchDemo {

    /**
     *【CountDownLatch 可以用来控制当前线程，是否可以执行（当内部数值为零时，可以执行，否则将被阻塞）】
     * 1、CountDownLatch 在实例化时，可以传递一个计数的数值；
     * 2、countDown() 方法，会将计数的数值减一，并且此方法并不会阻塞当前线程；
     * 3、当计数的数值不为零时，await() 方法会阻塞当前线程；
     * 4、当计数的数值为零后，所有被 await() 的线程都将被唤醒，然后开始执行；
     *【CountDownLatch 源码初识】
     * 1、底层用来计数的是一个 private volatile int state
     *    用 volatile 是为了保证 state 变量被多线程实时共享（避免变量被线程缓存后，内容不实时更新）；
     * 2、countDown()、await() 底层源码，还有待进一步学习；
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {

        CountDownLatch countDownLatch = new CountDownLatch(6);

        for (int i = 1; i <= 6 ; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t离开教室！");
                countDownLatch.countDown();
            },i + "").start();
        }

        countDownLatch.await();
        System.out.println("班长关门离开教室！");

    }

    /**
     * 多线程按照顺序执行：希望等 6 个子线程执行完之后，再执行主线程内容；（如下方法，无法实现希望的内容！）
     */
    private static void closeDoorDemo() {
        for (int i = 1; i <= 6 ; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + "\t离开教室！");
            },i + "").start();
        }

        System.out.println("班长关门离开教室！");
    }
}
